import { parse } from 'best-effort-json-parser';

const CODEBLOCK_REGEX = /```(?:json)?\s*([\s\S]*?)\s*```/gi;

const bestEffortParse: (input: string) => unknown = parse;

function tryParse<T>(candidate: string | undefined | null): T | null {
  if (!candidate) {
    return null;
  }

  const trimmed = candidate.trim();
  if (!trimmed) {
    return null;
  }

  try {
    return bestEffortParse(trimmed) as T;
  } catch (_) {
    return null;
  }
}

function scanFirstJsonObject<T>(text: string): T | null {
  let depth = 0;
  let inString = false;
  let start = -1;
  let prevChar = '';

  for (let i = 0; i < text.length; i++) {
    const char = text[i];

    if (char === '"' && prevChar !== '\\') {
      inString = !inString;
    }

    if (inString) {
      prevChar = char;
      continue;
    }

    if (char === '{') {
      if (depth === 0) {
        start = i;
      }
      depth++;
    } else if (char === '}') {
      depth--;
      if (depth === 0 && start !== -1) {
        const slice = text.slice(start, i + 1);
        const parsed = tryParse<T>(slice);
        if (parsed) {
          return parsed;
        }
        start = -1;
      }
    }

    prevChar = char;
  }

  return null;
}

function cleanCommonIssues(text: string): string {
  let cleaned = text.trim();
  cleaned = cleaned.replace(/^```(?:json)?\s*/i, '');
  cleaned = cleaned.replace(/```$/i, '');
  cleaned = cleaned.replace(/,\s*(?=[}\]])/g, '');
  cleaned = cleaned.replace(/\/\*[\s\S]*?\*\//g, '');
  cleaned = cleaned.replace(/(^|[^:])\/\/.*$/gm, '$1');
  return cleaned.trim();
}

export function extractJsonFromText<T = unknown>(raw: string, label = 'JSON'): T {
  console.log("Extracting json from text", 'raw:', raw, 'label:', label);
    const codeBlockMatch = raw.match(/```(?:json)?\s*([\s\S]*?)```/);
    if (codeBlockMatch) {
      try {
        return JSON.parse(codeBlockMatch[1].trim());
      } catch (e) {
        console.error('解析失败:', e);
        return null;
      }
    }
    return null;
}
